package com.example.beautymakeup.utils;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
import java.util.Date;
import java.util.UUID;

/*
* 这段代码是一个简单的Java类，用于生成和解析JSON Web Token（JWT）。
* JWT是一种用于在网络上传递信息的开放标准（RFC 7519），通常用于在用户和服务器之间传递经过签名的信息。
下面是对代码的逐行解释：

1.public class JwtUtil {: 定义了一个名为 JwtUtil 的公共类。
2.public static final Long JWT_TTL = 60 * 60 *1000L;: 定义了一个常量 JWT_TTL，表示JWT的过期时间，这里设置为1小时。
3.public static final String JWT_KEY = "huanfqc";: 定义了一个常量 JWT_KEY，表示JWT的秘钥明文，长度必须大于等于6位。
4.public static String getUUID(){...}: 定义了一个静态方法 getUUID()，用于生成UUID（通用唯一标识符）。
5.public static String createJWT(String subject) { ... }: 定义了一个静态方法 createJWT，用于生成JWT，其中参数 subject 是要存放在JWT中的数据（以JSON格式表示）。
6.public static String createJWT(String subject, Long ttlMillis) { ... }: 定义了另一个方法 createJWT，允许通过参数设置JWT的超时时间。
7.private static JwtBuilder getJwtBuilder(String subject, Long ttlMillis, String uuid) { ... }: 定义了一个私有静态方法 getJwtBuilder，该方法返回一个 JwtBuilder 实例，用于构建JWT。
8.SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;: 使用HS256对称加密算法指定签名算法。
9.SecretKey secretKey = generalKey();: 调用 generalKey() 方法生成一个秘钥。
10.long nowMillis = System.currentTimeMillis();: 获取当前时间的毫秒表示。
11.Date now = new Date(nowMillis);: 将当前时间转换为 Date 对象。
12.if(ttlMillis==null){ ttlMillis=JwtUtil.JWT_TTL; }: 如果没有传入超时时间，就使用默认的 JWT_TTL。
13.long expMillis = nowMillis + ttlMillis;: 计算JWT的过期时间。
14.Date expDate = new Date(expMillis);: 将过期时间转换为 Date 对象。
15.return Jwts.builder() ...: 使用 io.jsonwebtoken.Jwts 类的 builder() 方法开始构建JWT。
16..setId(uuid): 设置JWT的唯一ID。
17..setSubject(subject): 设置JWT的主题，通常是包含用户信息的JSON数据。
18..setIssuer("huanf"): 设置JWT的签发者。
19..setIssuedAt(now): 设置JWT的签发时间。
20..signWith(signatureAlgorithm, secretKey): 使用指定的签名算法和秘钥对JWT进行签名。
21..setExpiration(expDate): 设置JWT的过期时间。
22.}: 方法结束。

最后，createJWT 方法返回通过 .compact() 方法将JWT转换为字符串后的结果，即生成的JWT。JWT的签名部分主要用于验证JWT的完整性和真实性，确保在传输过程中没有被篡改。
* */


//JWT工具类
public class JwtUtil {

    //有效期为
    public static final Long JWT_TTL = 24 * 60 * 60 *1000L;// 60 * 60 *1000  一个小时
    //设置秘钥明文, 注意长度必须大于等于6位
    public static final String JWT_KEY = "money6";

//    用于生成UUID（通用唯一标识符）。
    public static String getUUID(){
        return UUID.randomUUID().toString().replaceAll("-", "");
    }

    /**
     * 生成jtw
     * @param subject token中要存放的数据（json格式）
     */
    public static String createJWT(String subject) {
        JwtBuilder builder = getJwtBuilder(subject, null, getUUID());// 设置过期时间
        return builder.compact();
    }

    /**
     * 生成jtw
     * @param subject token中要存放的数据（json格式）
     * @param ttlMillis token超时时间
     */
    public static String createJWT(String subject, Long ttlMillis) {
        JwtBuilder builder = getJwtBuilder(subject, ttlMillis, getUUID());// 设置过期时间
        return builder.compact();
    }

    public static void main(String[] args) throws Exception {
        Claims claims = parseJWT("eyJhbGciOiJIUzI1NiJ9.eyJqdGkiOiI4ZTVmZDZkNDEzZDg0MTM5YTIxNDYyNmZkYTE5MzI3NCIsInN1YiI6ImFkbWluIiwiaXNzIjoibW9uZXkiLCJpYXQiOjE3MDgzMzgyMTMsImV4cCI6MTcwODQyNDYxM30.AWkKPjPKiCFud1z6HRt9csgOnCiZPw2DSKz6snGUWlw");
        System.out.println(claims.getSubject());
    }


    /**
     * 创建token
     */
    public static String createJWT(String id, String subject, Long ttlMillis) {
        JwtBuilder builder = getJwtBuilder(subject, ttlMillis, id);// 设置过期时间
        return builder.compact();
    }



    private static JwtBuilder getJwtBuilder(String subject, Long ttlMillis, String uuid) {
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        SecretKey secretKey = generalKey();
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);
        if(ttlMillis==null){
            ttlMillis=JwtUtil.JWT_TTL;
        }
        long expMillis = nowMillis + ttlMillis;
        Date expDate = new Date(expMillis);
        return Jwts.builder()
                .setId(uuid)              //唯一的ID
                .setSubject(subject)   // 主题  可以是JSON数据
                .setIssuer("money")     // 签发者
                .setIssuedAt(now)      // 签发时间
                .signWith(signatureAlgorithm, secretKey) //使用HS256对称加密算法签名, 第二个参数为秘钥
                .setExpiration(expDate);
    }

    /**
     * 生成加密后的秘钥 secretKey
     */
    public static SecretKey generalKey() {
        byte[] encodedKey = Base64.getDecoder().decode(JwtUtil.JWT_KEY);
        return new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
    }

    /**
     * 解析
     *
     */
    public static Claims parseJWT(String jwt) throws Exception {
        SecretKey secretKey = generalKey();
        return Jwts.parser()
                .setSigningKey(secretKey)
                .parseClaimsJws(jwt)
                .getBody();
    }

}